package com.xhs.service.impl;

import com.xhs.service.ResetRule;
import com.xhs.service.SerialNumberService;
import com.xhs.utils.RedisUtil;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.time.LocalDateTime;

/**
 * @desc: 自动编号服务实现
 * @projectName: auto-number
 * @author: xhs
 * @date: 2025-03-12 周三 13:40
 * @version: JDK 21
 */
@Slf4j
@Service
public class SerialNumberServiceImpl implements SerialNumberService {

    @Resource
    private RedisUtil redisUtil;

    /**
     * 自动编号Redis Key的前缀
     */
    private static final String KEY_PREFIX = "AUTO_NUMBER:";

    /**
     * 生成全局唯一编号
     *
     * @param businessKey 业务标识（如 "order", "invoice"）
     * @param prefix      编号前缀（可选）
     * @param suffix      编号后缀（可选）
     * @param length      编号位数（可选）
     * @param resetRule   编号重置规则（可选）
     * @return 生成的编号，如 "ORD-20250312-0001"
     */
    @Override
    public String generate(String businessKey, String prefix, String suffix, Integer length, ResetRule resetRule) {
        if (!StringUtils.hasLength(businessKey)) {
            throw new IllegalArgumentException("businessKey 不能为空");
        }
        LocalDateTime now = LocalDateTime.now();
        // 获取当前周期的Key后缀
        String redisKey = buildRedisKey(businessKey, resetRule, now);

//        // 获取分布式锁
//        String lockKey = redisKey + ":lock";
//        RLock lock = redissonClient.getLock(lockKey);
        try {
//            lock.lock(); // 加锁，防止并发冲突
            // 生成序列号（Redis 原子操作）
            long sequence = redisUtil.incr(redisKey, 1);
            // 设置新 Key 的过期时间（可选）
            if (sequence == 1) {
                redisUtil.expire(redisKey, resetRule.expirationTime());
            }
            // 生成日期部分（年月或年月日）
            String datePart = resetRule.getKeySuffix(now);
            // 格式化编号
            return formatNumber(prefix, suffix, sequence, length, datePart);
        } finally {
//            lock.unlock();
        }
    }

    /**
     * 构建 Redis Key（包含重置规则后缀）
     *
     * @param businessKey businessKey 业务标识（如 "order", "invoice"）
     * @param resetRule   编号重置规则
     * @param currentTime 日期
     * @return String
     */
    private String buildRedisKey(String businessKey, ResetRule resetRule, LocalDateTime currentTime) {
        if (resetRule == null) {
            return businessKey; // 无重置规则
        }
        return KEY_PREFIX + businessKey + ":" + resetRule.getKeySuffix(currentTime);
    }

    /**
     * 格式化最终编号
     *
     * @param prefix   前缀（可选）
     * @param suffix   后缀（可选）
     * @param sequence 序列号
     * @param length   序列号位数（不包括前缀、后缀和日期部分）
     * @param datePart 日期部分（如 "202503" 或 "20250301"）
     * @return String
     */
    private String formatNumber(String prefix, String suffix, Long sequence, Integer length, String datePart) {
        // 格式化序列号
        String seqStr = (length != null) ? String.format("%0" + length + "d", sequence) : sequence.toString();
        // 拼接前缀、日期部分、序列号和后缀
        StringBuilder result = new StringBuilder();
        if (StringUtils.hasLength(prefix)) {
            // 前缀 + 分隔符 + 日期部分 + 序列号
            result.append(prefix).append("-").append(datePart).append(seqStr);
        } else {
            // 日期部分 + 序列号
            result.append(datePart).append(seqStr);
        }
        if (StringUtils.hasLength(suffix)) {
            // 分隔符 + 后缀
            result.append("-").append(suffix);
        }
        return result.toString();
    }
}
